package com.ncepu.thumb.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ncepu.thumb.constant.RedisLuaScriptConstant;
import com.ncepu.thumb.constant.ThumbConstant;
import com.ncepu.thumb.exception.BusinessException;
import com.ncepu.thumb.exception.ErrorCode;
import com.ncepu.thumb.mapper.ThumbMapper;
import com.ncepu.thumb.model.dto.DoThumbRequest;
import com.ncepu.thumb.model.entity.Thumb;
import com.ncepu.thumb.model.entity.User;
import com.ncepu.thumb.model.enums.LuaStatusEnum;
import com.ncepu.thumb.service.ThumbService;
import com.ncepu.thumb.service.UserService;
import com.ncepu.thumb.utils.RedisKeyUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Arrays;

/**
* @author 14563
* @description 针对表【thumb】的数据库操作Service实现
* @createDate 2025-05-10 21:18:30
*/
//@Primary
@Service("thumbServiceRedis")
@Slf4j
@RequiredArgsConstructor
public class ThumbServiceRedisImpl extends ServiceImpl<ThumbMapper, Thumb>
    implements ThumbService{

    private final UserService userService;
    private final RedisTemplate<String, Object> redisTemplate;

    @Override
    public Boolean doThumb(DoThumbRequest doThumbRequest, HttpServletRequest request) {
        if(doThumbRequest == null || doThumbRequest.getBlogId() == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        Long blogId = doThumbRequest.getBlogId();
        User loginUser = userService.getLoginUser(request);
        if(loginUser == null){
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR, "用户未登录");
        }

        String timeSlice = getTimeSlice();
        String tempThumbKey = RedisKeyUtil.getTempThumbKey(timeSlice);
        String userThumbKey = RedisKeyUtil.getUserThumbKey(loginUser.getId());
        String blogsExistedKey = RedisKeyUtil.getBlogsExistedKey();

        // 执行Lua脚本
        Long result = redisTemplate.execute(
                RedisLuaScriptConstant.THUMB_SCRIPT, // Lua脚本
                Arrays.asList(tempThumbKey, userThumbKey, blogsExistedKey), // KEYS参数
                loginUser.getId(), // ARGV[1]参数
                blogId, // ARGV[2]参数
                System.currentTimeMillis() // ARGV[3]参数
        );
        if(LuaStatusEnum.NO_BLOG.getValue() == result) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "博客不存在");
        }
        if(LuaStatusEnum.FAIL.getValue() == result) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户已点赞");
        }

        return LuaStatusEnum.SUCCESS.getValue() == result;
    }

    @Override
    public Boolean undoThumb(DoThumbRequest doThumbRequest, HttpServletRequest request) {
        if(doThumbRequest == null || doThumbRequest.getBlogId() == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        Long blogId = doThumbRequest.getBlogId();
        User loginUser = userService.getLoginUser(request);
        if(loginUser == null){
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR, "用户未登录");
        }

        String timeSlice = getTimeSlice();
        String tempThumbKey = RedisKeyUtil.getTempThumbKey(timeSlice);
        String userThumbKey = RedisKeyUtil.getUserThumbKey(loginUser.getId());
        String blogsExistedKey = RedisKeyUtil.getBlogsExistedKey();

        // 执行Lua脚本
        Long result = redisTemplate.execute(
                RedisLuaScriptConstant.UNTHUMB_SCRIPT, // Lua脚本
                Arrays.asList(tempThumbKey, userThumbKey, blogsExistedKey), // KEYS参数
                loginUser.getId(), // ARGV[1]参数
                blogId // ARGV[2]参数
        );
        if(LuaStatusEnum.NO_BLOG.getValue() == result) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "博客不存在");
        }
        if(LuaStatusEnum.FAIL.getValue() == result) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户未点赞");
        }

        return LuaStatusEnum.SUCCESS.getValue() == result;
    }

    private String getTimeSlice() {
        DateTime nowDate = DateUtil.date();
        return DateUtil.format(nowDate, "HH:mm:") + (DateUtil.second(nowDate) / 10) * 10;
    }

    @Override
    public Boolean hasThumb(Long blogId, Long userId) {

        Double score = redisTemplate.opsForZSet().score(ThumbConstant.USER_THUMB_KEY_PREFIX + userId, blogId);
        return score != null;
    }
}




